<?php

namespace App\Models\Article;

use App\Models\Common\CommonModel;
use App\Models\Constant\Constant;
use App\Models\Constant\FileConstant;
use App\Models\User\Favorite;
use DOMXPath;
use HTMLPurifier;
use HTMLPurifier_Config;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Arr;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;
use DOMDocument;

class ArticleInfo extends CommonModel
{
    use HasFactory;

    protected $table = 'article_info';

    protected $appends = ['price','summary','cover','thumb','has_word','human_time'];

    /**
     * 获取置顶的三篇教程
     * @return mixed
     * @throws \Exception
     */
    public function getTopRecords() {
        $cols = ['id','title','type','publish_at'];
        cache()->remember('topRecords', 3600*24, function () use ($cols) {
            return ArticleInfo::whereIn('id',[7011,7010,7283])->get($cols);
        });
        return Cache::get('topRecords');
    }

    /**
     * 获取热词
     * @param $exchangeCode
     * @return array
     */
    public function getHotWords($from):array {
        $hotWords = ['二十大', '总结', '述职', '述责述廉', '民主生活', '组织生活', '党课讲稿'];
        if($from==Constant::FROM_CTBSC){
            $hotWords[] = 'PPT';
        }
        return $hotWords;
    }

    /**
     * 获取文章总数
     * @return int
     * @throws \Exception
     */
    public function getArticleCount():int {
        cache()->remember('countArticle', 3600*6, function () {
            return ArticleInfo::query()->where('publish_at','<=',date('Y-m-d H:i:s'))->orderByDesc('id')
                ->limit(1)->first(['id'])->id??1;
        });
        return Cache::get('countArticle');
    }

    /**
     * 获取今日更新文章总数
     * @return int
     * @throws \Exception
     */
    public function getTodayUpdateCount($from):int {
        cache()->remember('todayCount', 3600*3, function () {
            return ArticleInfo::query()->whereDate('publish_at',date('Y-m-d'))
                ->where('publish_at','<=',date('Y-m-d H:i:s'))
                ->count();
        });
        $todayCount = Cache::get('todayCount');
        //副网站的文章数是真实的
        if($todayCount>0 && $from==Constant::FROM_CTBSC) {
            $todayCount = (in_array(date('Y-m-d'), Constant::MAP_UNWOKDAY) || Carbon::now()->isWeekend())?$todayCount+10:$todayCount+20;
        }

        return $todayCount;
    }

    public function getTodayRecords(int $limit) {
        $cols = ['id','title','type','publish_at'];
        cache()->remember('allTodayRecords', 3600*3, function () use ($limit,$cols) {
            return  ArticleInfo::query()
                ->whereDate('publish_at', date('Y-m-d'))
                ->where('publish_at','<=',date('Y-m-d H:i:s'))
                ->orderByDesc('id')
                ->get($cols)->toArray();
        });
        $allTodayRecords = Cache::get('allTodayRecords');
        cache()->remember('limitTodayRecords', 3600*3, function () use ($allTodayRecords,$limit) {
            //return  $allTodayRecords->take($limit);
            return  array_slice($allTodayRecords,0,$limit);
        });
        $limitTodayRecords = Cache::get('limitTodayRecords');

        return compact('allTodayRecords', 'limitTodayRecords');
    }

    public function getPPtRecords(int $limit) {
        cache()->remember('pptRecords', 3600*3, function () use ($limit) {
            return  ArticleInfo::query()->where('type','pptx')->orderByDesc('id')->limit($limit)->get()->each(function ($item) {
                $item->publish_at = date('m-d',strtotime($item->publish_at));
            })->toArray();
        });
        return Cache::get('pptRecords');
    }



    public function getHumanTimeAttribute() {
        return date('m-d',strtotime($this->publish_at));
    }
    public function getTitleAttribute($value) {
        return Str::replace(['民主生活会','组织生活会'], ['xxxxx','组织xxx'], $value);
    }

    public function getPriceAttribute(){
        return $this->type=='pptx'?'5.0':'3.5';
    }

    public function getCoverAttribute(){
        if($this->type=='pptx')
            return Arr::first(explode(',',$this->img_urls));
        else
            return '';
    }

    public function getThumbAttribute($value) {
        if($this->type=='pptx')
            $imgs = explode(',',$this->img_urls);
            return isset($imgs[1])?$imgs[1]:'';
    }

    public function getHasWordAttribute() {
        if($this->type=='pptx' && !empty($this->docx_url)){
            return true;
        }else{
            return false;
        }
    }

    public function getSummaryAttribute(){
        if(empty($this->content))return '';

        return $this->truncateHtmlWithDOMDocument($this->content,1000);
    }

    function truncateHtmlWithDOMDocument($html, $length = 100, $end = '...') {
        $dom = new DOMDocument();
        @$dom->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
        $dom->preserveWhiteSpace = false;

        $body = $dom->getElementsByTagName('body')->item(0);
        $content = '';
        foreach ($body->childNodes as $node) {
            $content .= $dom->saveHTML($node);
            if (mb_strlen($content) > $length) {
                break;
            }
        }
        if (mb_strlen($content) > $length) {
            $content = mb_substr($content, 0, strrpos(mb_substr($content, 0, $length), ' ')) . $end;
        } elseif (mb_strlen($content) < mb_strlen($html)) {
            $content .= $end;
        }
        return $content;
    }


    public function getClassify() {
        return $this->hasOne(ArticleClassify::class,'id','classify_id')->withDefault(['name'=>'未知']);
    }

    public function getRecords(array $conditions): Builder {
        $records = parent::getRecords($conditions); // TODO: Change the autogenerated stub
        if(!empty($conditions['classifyId']) && $conditions['classifyId']!=FileConstant::CLASSIFY_ID_ALL){
            $records = is_array($conditions['classifyId'])?
                $records->whereIn('classify_id', $conditions['classifyId']):$records->where('classify_id',$conditions['classifyId']);
        }
        if(!empty($conditions['upDown'])){
            $records = $records->where('up_down',$conditions['upDown']);
        }
        if(!empty($conditions['title']) ){

            if(Str::contains($conditions['title'],' ')){
                $words = array_filter(explode(' ', $conditions['title']));
                if(count($words)>0){
                    /*foreach ($words as $word) {
                        $ins = Word::where(compact('word'))->first();
                        if(empty($ins))Word::create(compact('word'));
                        else{
                            $ins->count +=1;
                            $ins->save();
                        }
                    }*/
                    //$records = $records->where('title','like','%'.implode('%', $words).'%');
                    $records = $records->where(function ($q) use ($words) {
                        $q->where('title','like','%'.$words[0].'%');
                        if(isset($words[1]))$q->where('title','like','%'.$words[1].'%');
                        if(isset($words[2]))$q->where('title','like','%'.$words[2].'%');
                        if(isset($words[3]))$q->where('title','like','%'.$words[3].'%');
                        if(isset($words[4]))$q->where('title','like','%'.$words[4].'%');
                        if(isset($words[5]))$q->where('title','like','%'.$words[5].'%');
                        if(isset($words[6]))$q->where('title','like','%'.$words[6].'%');
                        if(isset($words[7]))$q->where('title','like','%'.$words[7].'%');
                        if(isset($words[8]))$q->where('title','like','%'.$words[8].'%');
                        if(isset($words[9]))$q->where('title','like','%'.$words[9].'%');
                    });
                }
            }else{
                /*$word = $conditions['title'];
                $ins = Word::where(compact('word'))->first();
                if(empty($ins))Word::create(compact('word'));
                else{
                    $ins->count +=1;
                    $ins->save();
                }*/
                $records = $records->where('title','like','%'.$conditions['title'].'%');
            }



        }

        if(!empty($conditions['keyWord']) ){
            $records = $records->where('key_word','like','%'.$conditions['keyWord'].'%');
        }
        if(!empty($conditions['summary']) ){
            $records = $records->where('summary','like','%'.$conditions['description'].'%');
        }
        if(!empty($conditions['content']) ){
            $records = $records->where('content','like','%'.$conditions['content'].'%');
        }
        if(!empty($conditions['date']) ){
            $records = $records->whereDate('created_at',$conditions['date']);
        }
        if(!empty($conditions['year']) ){
            $records = $records->whereYear('year',$conditions['year']);
        }
        if(!empty($conditions['month']) ){
            $records = $records->whereMonth('month',$conditions['month']);
        }
        //return $records->orderBy('is_top')->orderBy('id','desc');
        return $records->orderBy('id','desc');
    }

    public function isFavoriteByUserId($userId):bool{
        return Favorite::query()->where(['user_id'=>$userId??0,'article_id'=>$this->id])->exists();
    }




}
